/**
 * 广寒宫
 * 网址:www.guanghangong.xyz
 */
package com.moon.admin.framework.springmvc;

import java.util.Optional;

import javax.servlet.Filter;

import com.moon.admin.framework.cache.CacheService;
import com.moon.admin.framework.cache.LocalCacheProviderImpl;
import com.moon.admin.framework.cache.RedisCacheProviderImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.OncePerRequestFilter;

import com.moon.admin.framework.springmvc.properties.SpringMvcCorsProperties;
import com.moon.admin.framework.springmvc.properties.SpringMvcLogProperties;

/**
 * @author ninglong
 */
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties({ SpringMvcLogProperties.class,SpringMvcCorsProperties.class })
@Slf4j
public class SpringMvcAutoConfiguration {

	@Bean
	@ConditionalOnClass(CorsFilter.class)
	@ConditionalOnProperty(value = "moon.web.springmvc.cors.enabled")
	public Filter corsFilter(SpringMvcCorsProperties springMvcCorsProperties) {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration(Optional.ofNullable(springMvcCorsProperties.getPath())
						.orElse("/**"), buildConfig(springMvcCorsProperties));
		return new CorsFilter(source);
	}

	private CorsConfiguration buildConfig(SpringMvcCorsProperties springMvcCorsProperties) {
		CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.setAllowedOriginPatterns(springMvcCorsProperties.getAllowOrigins());
		Optional.ofNullable(springMvcCorsProperties.getAllowHeaders())
				.ifPresent(headers -> headers.forEach(corsConfiguration::addAllowedHeader));
		Optional.ofNullable(springMvcCorsProperties.getAllowMethods())
				.ifPresent(methods -> methods.forEach(corsConfiguration::addAllowedMethod));
		Optional.ofNullable(springMvcCorsProperties.getAllowExposeHeaders())
				.ifPresent(headers -> headers.forEach(corsConfiguration::addExposedHeader));
		corsConfiguration.setAllowCredentials(true);
		return corsConfiguration;
	}

	@Bean
	@ConditionalOnClass(OncePerRequestFilter.class)
	@ConditionalOnProperty(value = "moon.web.springmvc.log.enabled", matchIfMissing = true)
	public Filter accessLogFilter(SpringMvcLogProperties springMvcLogProperties) {
		return new AccessLogFilter(springMvcLogProperties);
	}

	@Bean
	public CacheService cacheService(RedisProperties redisProperties){
		if("localhost".equals(redisProperties.getHost())){
			log.info("系统将启用Guava缓存...");
			return new LocalCacheProviderImpl();
		}else{
			log.info("系统将启用redis缓存...");
			return new RedisCacheProviderImpl();
		}
	}
}